
package com.smyh.util;


import org.apache.mina.core.buffer.IoBuffer;
/**
 * 
* 创建日期:May 30, 2011 11:45:01 AM
* Title:输电线路状态监测系统
* Description：CRC校验工具类
* @author sunlei
* @mender：（文件的修改者，文件创建者之外的人）
* @version 1.0
* Remark：认为有必要的其他信息
 */

public class CrcValid {

/**
	 * 
	* @desc: CRC算法,返回给定byte数组的CRC16校验结果
	* @author: zuyc
	* @create-time:@date 2013-1-25 上午10:27:47
	* @param byteArr
	* @return 
	 */

	public static byte[] rtu_crc(byte[] byteArr) {
		int j = 0;
		long crc = 0xffffL; // CRC校验结果long型
		short dex = 0;
		for (int i = 0; i <= byteArr.length - 1; i++) { // 2.把第一个8位二进制数据（既通讯信息帧的第一个字节）与16位的CRC寄存器的低8位相异或，把结果放于CRC寄存器；
			dex = (short) ((crc % 256L) ^ byteArr[i]);
			if (dex < 0)
				dex = (short) ((-Byte.MIN_VALUE + Byte.MAX_VALUE) + 1 + dex);
			crc = (crc / 256) * 256L + dex;
			for (j = 0; j <= 7; j++) { // 3.把CRC寄存器的内容右移一位（朝低位）用0填补最高位，并检查最低位；
				// 4.如果最低位为0：重复第3步（再次右移一位）；
				// 如果最低位为1：CRC寄存器与多项式A001（1010 0000 0000 0001）进行异或；
				// 5.重复步骤3和4，直到右移8次，这样整个8位数据全部进行了处理；
				long d0 = 0;
				d0 = crc & 1L;
				crc = crc / 2;
				if (d0 == 1)
					crc = crc ^ 0xa001L;
			} // 6.重复步骤2到步骤5，进行通讯信息帧下一字节的处理；
		} // 7.最后得到的CRC寄存器内容即为：CRC码。
		crc = crc % 65536;
		
		byte[] crcResult = new byte[2];
		crcResult[0] = (byte)(crc / 256); // 低位字符串
		crcResult[1] = (byte)(crc % 256); // 高位字符串
		
		return crcResult;
	}
	
	public static byte[] rtu_crc(IoBuffer buffer,int start,int end){
		byte[] byteArr = new byte[end - start +1];
		for(int i = start;i<end;i++){
			byteArr[i-start] = buffer.get(i);
		}
		return rtu_crc( byteArr);
	}
	
}

